package com.greateamd.timetableasy.client.mvc.view.crud.planning;

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.DateBox;
import com.greateamd.timetableasy.client.domain.AuthType;
import com.greateamd.timetableasy.client.domain.EventType;
import com.greateamd.timetableasy.client.mvc.model.Model;
import com.greateamd.timetableasy.client.mvc.model.PlanningModel;
import com.greateamd.timetableasy.client.mvc.view.TimeTableasyPage;
import com.greateamd.timetableasy.client.mvc.view.crud.event.AddEventPage;
import com.greateamd.timetableasy.client.widgets.planning.PlanningWidget;
import com.greateamd.timetableasy.client.widgets.planning.PlanningWidget.PlanningType;
import com.greateamd.timetableasy.domain.Auth;
import com.greateamd.timetableasy.domain.Event;
import com.greateamd.timetableasy.domain.User;


public abstract class PlanningPage <M extends PlanningModel> extends IPlanningPage<M> {
	
	@UiTemplate("PlanningPage.ui.xml")
	interface PlanningPageUIBinder extends UiBinder<Widget, PlanningPage> {}
	private static PlanningPageUIBinder uiBinder = GWT.create(PlanningPageUIBinder.class);
	
	protected M model;
	
	@UiField SimplePanel extraPanel;
	
	@UiField PlanningWidget planning;
	
	//Date & Type
	@UiField DateBox fromDb;
    @UiField RadioButton byDayRb;
    @UiField RadioButton byWeekRb;
    @UiField RadioButton byMonthRb;
    //Optional
    @UiField CheckBox optionalEventUser;
    @UiField CheckBox optionalEventPromotion;
    @UiField CheckBox optionalEventStudyPeriod;
    @UiField CheckBox optionalEventCampus;
    @UiField CheckBox optionalEventUniversity;
    //Add event
    @UiField MenuItem addEventUser;
    @UiField MenuItem addEventPromotion;
    @UiField MenuItem addEventSp;
    @UiField MenuItem addEventCampus;
    @UiField MenuItem addEventUniversity;
    //
	@UiField Button submitBt;
	
	public PlanningPage(M model) {
		initWidget(uiBinder.createAndBindUi(this));
		this.model = model;
		initAddEventPanel();
	}
	
	//---------------------------------------------------------------------
	//-------------------------- Handler
	@UiHandler("submitBt")
	void onSubmitBtClick(ClickEvent e){
		callServerEvent();
	}
	//Mandatories events
	@UiHandler("optionalEventUser")
	void onOptionalEventUser(ClickEvent e){
		model.setOptionalEventUser(optionalEventUser.getValue());
	}
	@UiHandler("optionalEventPromotion")
	void onOptionalEventPromotion(ClickEvent e){
		model.setOptionalEventPromotion(optionalEventPromotion.getValue());
	}
	@UiHandler("optionalEventStudyPeriod")
	void onOptionalEventStudyPeriod(ClickEvent e){
		model.setOptionalEventStudyPeriod(optionalEventStudyPeriod.getValue());
	}
	@UiHandler("optionalEventCampus")
	void onOptionalEventCampus(ClickEvent e){
		model.setOptionalEventCampus(optionalEventCampus.getValue());
	}
	@UiHandler("optionalEventUniversity")
	void onOptionalEventUniversity(ClickEvent e){
		model.setOptionalEventUniversity(optionalEventUniversity.getValue());
	}

	//---------------------------------------------------------------------
	//-------------------------- UI
	/**
	 * Actualize the planning state in function of the form values
	 */
	protected void refreshPlanning(final TimeTableasyPage pageViewRequest) {
		if(!model.getFilteredEvents().isEmpty()){
			PlanningType typeOfPlanning;
			if(byDayRb.getValue()){
				typeOfPlanning = PlanningType.DAY;
			}else if(byWeekRb.getValue()){
				typeOfPlanning = PlanningType.WEEK;
			}else{
				typeOfPlanning = PlanningType.MONTH;
			}
			planning.setStartDate(fromDb.getValue(),typeOfPlanning);
			for(Event e : model.getFilteredEvents()){
				planning.addEvent(e,model.getUser(),pageViewRequest);
			}
		} else { //No events to represent
			Window.alert("No events found");
		}
	}

	private void initAddEventPanel() {
		//--------- User
		addEventUser.setCommand(new Command() {
			@Override
			public void execute() {
				showAddEventPage(EventType.USER);
			}
		});
		if(model.getUser().getAuths().contains(new Auth(model.getUser(),AuthType.ROLE_CAMPUS_MANAGER))){
			//--------- Promotion
			addEventPromotion.setVisible(true);
			addEventPromotion.setCommand(new Command() {
				@Override
				public void execute() {
					showAddEventPage(EventType.PROMOTION);
				}
			});
			//--------- Campus
			addEventCampus.setVisible(true);
			addEventCampus.setCommand(new Command() {
				@Override
				public void execute() {
					showAddEventPage(EventType.PROMOTION);
				}
			});
		}
		
		if(model.getUser().getAuths().contains(new Auth(model.getUser(),AuthType.ROLE_ADMIN))){
			//--------- StudyPeriod
			addEventSp.setVisible(true);
			addEventSp.setCommand(new Command() {
				@Override
				public void execute() {
					showAddEventPage(EventType.STUDY_PERIOD);
				}
			});
			//--------- University
			addEventUniversity.setVisible(true);
			addEventUniversity.setCommand(new Command() {
				@Override
				public void execute() {
					showAddEventPage(EventType.UNIVERSITY);
				}
			});
		}
	}
	
	private void showAddEventPage(EventType type){
		final PopupPanel p = new PopupPanel(false,true);
		p.setAnimationEnabled(true);
		p.setGlassEnabled(true);
		final HorizontalPanel hp = new HorizontalPanel();
		hp.add(new AddEventPage<Model>(model, type));
		hp.add(new Button("Close",new ClickHandler() {
			@Override
			public void onClick(ClickEvent arg0) {
				p.hide();
			}
		}));
		p.setWidget(hp);
		p.show();
		p.center();
	}
	

	//---------------------------------------------------------------------
	//-------------------------- Business
	protected Date getToDate() {
		final Date toDate = CalendarUtil.copyDate(fromDb.getValue());
		if(byDayRb.getValue()){
			toDate.setHours(0);
			CalendarUtil.addDaysToDate(toDate, 1);
		} else if(byWeekRb.getValue()){
			CalendarUtil.addDaysToDate(toDate, 6);
		}else if(byMonthRb.getValue()){
			CalendarUtil.addMonthsToDate(toDate, 1);
		}
		return toDate;
	}
	
	@Override
	protected void setExtraPanel(Widget widget) {
		extraPanel.setWidget(widget);
	}
	
	@Override
	protected void setUser(User user) {
		this.model.setUser(user);
	}
	
	@Override
	protected Date getFromDate() {
		Date from = fromDb.getValue();
		from.setHours(0);
		return from;
	}
}
